In [7]:
library(rstatix)
library(dplyr) 
library(ggplot2) 

# A small function helping us to round  all numbers (0.123456 -> 0.123)
round_df <- function(df, digits = 3) {
    nums <- vapply(df, is.numeric, FUN.VALUE = logical(1))
    df[,nums] <- round(df[,nums], digits = digits)
    (df)
}

# Loading the CSV file
df <- read.csv("data-wpm-onefactorial.csv") 

# Show header if everything is OK
head(df)
 
# Check if data is normal distributed
round_df(df %>% group_by(Conditions) %>% shapiro_test(WPM))

# Nothing is significant, so we can run a three-way repeated-measures ANOVA
anova <- anova_test(data = df, dv = WPM, wid = SubjectID, within = Conditions,  effect.size = "pes")

# Auto correction of degree of freedom (if necessary)
get_anova_table(anova, correction = "auto")

# Pairwise Posthoc Comparison to understand where the differences occur
pairwise.t.test(df$WPM, df$Conditions, p.adj = "bonf", paired = TRUE)

# Let's aggregate the data
means <- df %>% group_by(Conditions) %>% summarize(
    Mean = mean(WPM),
    SD = sd(WPM),
    N = n(), .groups = 'drop',) %>% mutate(
    SE = SD / sqrt(N),
    CI = qt(1 - (0.05 / 2), N - 1) * SE) 

# Let's plot the data
plot <- ggplot(means, aes(y=Mean, x=Conditions, fill=Conditions)) +  
                    geom_bar(stat = "identity") + 
                    geom_errorbar(aes(ymin=Mean-CI, ymax=Mean+CI, width=.1)) + 
                    ylab("words per minute (WPM)") + 
                    xlab("")+
                    ggtitle("Typing performance") +
                    theme_minimal() +  
                    theme( 
                        legend.margin=margin(t = -5, unit='mm'),
                        plot.margin=unit(x=c(1,2,1,1),units="mm"),
                        legend.position = "none",
                        legend.title = element_blank(),
                        plot.title = element_text(hjust = 0.5), 
                        panel.background = element_rect(size=0.5, color="transparent", fill="gray98" )
                    ) 

options(repr.plot.width = 5, repr.plot.height = 5)

plot
ggsave("Swipe-WPM-BarChart.pdf", plot, width=5, height=5, device=cairo_pdf)
A data.frame: 6 × 4
SubjectIDSequenceConditionsWPM
<int><int><chr><dbl>
111NoSwipe 44.559
212Swipe 75.381
313VibroSwipe88.695
421NoSwipe 42.951
522VibroSwipe95.790
623Swipe 76.255
A tibble: 3 × 4
Conditionsvariablestatisticp
<chr><chr><dbl><dbl>
NoSwipe WPM0.8880.111
Swipe WPM0.9790.979
VibroSwipeWPM0.9270.350
A anova_test: 1 × 7
EffectDFnDFdFpp<.05pes
<chr><dbl><dbl><dbl><dbl><chr><dbl>
1Conditions22224.2552.73e-06*0.688
	Pairwise comparisons using paired t tests 

data:  df$WPM and df$Conditions 

           NoSwipe Swipe  
Swipe      0.00012 -      
VibroSwipe 0.00022 1.00000

P value adjustment method: bonferroni 
In [8]:
library(rstatix)
library(dplyr) 
library(ggplot2) 

# A small function helping us to round  all numbers (0.123456 -> 0.123)
round_df <- function(df, digits = 3) {
    nums <- vapply(df, is.numeric, FUN.VALUE = logical(1))
    df[,nums] <- round(df[,nums], digits = digits)
    (df)
}

# Loading the CSV file
df <- read.csv("data-tlx-onefactorial.csv") 

# Show header if everything is OK
head(df)

# TLX = Mental Demand + Phyiscal Demand + Temporal Demand + Performance + Effort + Frustration
df$TLX <- df$MD + df$PD + df$TD + df$PE + df$EF + df$FR

# Check if data is normal distributed
round_df(df %>% group_by(Conditions) %>% shapiro_test(TLX))

# Nothing is significant, so we can run a three-way repeated-measures ANOVA
anova <- anova_test(data = df, dv = TLX, wid = SubjectID, within = Conditions,  effect.size = "pes")

# Auto correction of degree of freedom (if necessary)
get_anova_table(anova, correction = "auto")

# Pairwise Posthoc Comparison to understand where the differences occur
pairwise.t.test(df$TLX, df$Conditions, p.adj = "bonf", paired = TRUE)

# Let's aggregate the data
means <- df %>% group_by(Conditions) %>% summarize(
    Mean = mean(TLX),
    SD = sd(TLX),
    N = n(), .groups = 'drop',) %>% mutate(
    SE = SD / sqrt(N),
    CI = qt(1 - (0.05 / 2), N - 1) * SE) 

# Let's plot the data
plot <- ggplot(means, aes(y=Mean, x=Conditions, fill=Conditions)) +  
                    geom_bar(stat = "identity") + 
                    geom_errorbar(aes(ymin=Mean-CI, ymax=Mean+CI, width=.1)) + 
                    ylab("words per minute (WPM)") + 
                    xlab("")+
                    ggtitle("Typing performance") +
                    theme_minimal() +  
                    theme( 
                        legend.margin=margin(t = -5, unit='mm'),
                        plot.margin=unit(x=c(1,2,1,1),units="mm"),
                        legend.position = "none",
                        legend.title = element_blank(),
                        plot.title = element_text(hjust = 0.5), 
                        panel.background = element_rect(size=0.5, color="transparent", fill="gray98" )
                    ) 

options(repr.plot.width = 5, repr.plot.height = 5)

plot
ggsave("Swipe-WPM-BarChart.pdf", plot, width=5, height=5, device=cairo_pdf)
A data.frame: 6 × 9
SubjectIDSequenceConditionsMDPDTDPEEFFR
<int><int><chr><int><int><int><int><int><int>
111NoSwipe 111129 6 0
212Swipe 101112910 7
313VibroSwipe12 3 701010
421NoSwipe 1 6 32 210
522VibroSwipe12 4138 1 9
623Swipe 4 8 58 5 8
A tibble: 3 × 4
Conditionsvariablestatisticp
<chr><chr><dbl><dbl>
NoSwipe TLX0.9290.368
Swipe TLX0.9100.216
VibroSwipeTLX0.9610.804
A anova_test: 1 × 7
EffectDFnDFdFpp<.05pes
<chr><dbl><dbl><dbl><dbl><chr><dbl>
1Conditions2224.4050.025*0.286
	Pairwise comparisons using paired t tests 

data:  df$TLX and df$Conditions 

           NoSwipe Swipe
Swipe      0.110   -    
VibroSwipe 0.099   1.000

P value adjustment method: bonferroni